package cn.edu.jxust.core.domain.repository.impl;

import cn.edu.jxust.common.domain.entity.Account;
import cn.edu.jxust.common.domain.entity.Enterprise;
import cn.edu.jxust.common.domain.valobj.EnterpriseVo;
import cn.edu.jxust.core.infrastructure.mapper.AccountMapper;
import cn.edu.jxust.core.infrastructure.mapper.AreaMapper;
import cn.edu.jxust.core.infrastructure.mapper.EnterpriseMapper;
import cn.edu.jxust.core.infrastructure.mapper.PollutionsourcetypeMapper;
import cn.edu.jxust.core.infrastructure.mapper.RegulationtypeMapper;
import cn.edu.jxust.core.infrastructure.mapper.TradetypeMapper;
import cn.edu.jxust.common.response.Result;
import cn.edu.jxust.common.response.ResultUtils;
import cn.edu.jxust.common.response.enums.ResultStatus;
import cn.edu.jxust.core.domain.repository.DeviceService;
import cn.edu.jxust.core.domain.repository.EnterpriseService;
import cn.edu.jxust.core.domain.repository.SiteService;
import cn.edu.jxust.core.infrastructure.util.Const;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author QiuKangming
 * @since 2020-06-29
 */
@Service
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements EnterpriseService {

    @Resource
    private EnterpriseMapper enterpriseMapper;
    @Resource
    private AreaMapper areaMapper;
    @Resource
    private AccountMapper accountMapper;
    @Resource
    private TradetypeMapper tradetypeMapper;
    @Resource
    private PollutionsourcetypeMapper pstm;
    @Resource
    private RegulationtypeMapper regulationMapper;
    @Resource
    private DeviceService deviceService;
    @Resource
    private SiteService siteService;

    /**
     * 根据企业名字和区域id查找企业信息
     * @param areaId 区域id
     * @param name 企业名称
     * @return Enterprise
     */
    @Override
    public Enterprise findByNameAndAreaId(Integer areaId, String name) {

        return enterpriseMapper.selectOne(new QueryWrapper<Enterprise>()
                .eq("area_id", areaId)
                .eq("enterprise_name", name));

    }

    /**
     * 根据企业id查找企业名称
     * @param id 企业id
     * @return String
     */
    @Override
    public String getEnterpriseNameById(Integer id) {

        return enterpriseMapper.selectById(id).getEnterpriseName();

    }

    /**
     * 新增企业信息
     * @param enterpriseVo 企业视图对象
     * @return Result
     */
    @Override
    public Result addEnterprise(EnterpriseVo enterpriseVo) {

        //检查是否存在该企业
        Enterprise search = this.findByNameAndAreaId(enterpriseVo.getAreaId(), enterpriseVo.getEnterpriseName());
        if(null != search){
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "该企业信息已存在");
        }
        Enterprise enterprise = new Enterprise();
        //判断企业法定负责人和环保负责人
        String lawuserName = enterpriseVo.getLawuserName();
        String environmentuserName = enterpriseVo.getEnvironmentuserName();
        if(lawuserName != null){
            Account lawuserAccount = accountMapper.getByAccName(lawuserName);
            if(lawuserAccount != null){
                enterpriseVo.setLawUserid(lawuserAccount.getId());
            }else{
                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "企业法定代表人名字有误或该企业不存在该用户");
            }
        }
        if(environmentuserName != null){
            Account environmentuserAccount = accountMapper.getByAccName(environmentuserName);
            if(environmentuserAccount != null){
                enterpriseVo.setEnvironmentUserid(environmentuserAccount.getId());
            }else{
                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "企业环保负责人名字有误或该企业不存在该用户");
            }
        }

        BeanUtil.copyProperties(enterpriseVo, enterprise);
        return enterpriseMapper.insert(enterprise) == 1
                ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "添加企业信息成功")
                : ResultUtils.resultWithoutData(ResultStatus.FAILED, "添加企业信息失败");

    }

    /**
     * 根据 id 删除企业信息
     * @param id 企业id
     * @return Result
     */
    @Override
    public Result delEnterpriseById(Integer id) {

        //获取当前登录用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        if(account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            return ResultUtils.resultWithoutData(ResultStatus.VISITED_FORBID);
        }
        //检查是否存在该企业
        Enterprise enterprise = this.getById(id);
        if(null == enterprise){
            return ResultUtils.resultWithoutData(ResultStatus.NOT_FOUND, "不存在该企业信息");
        }

        if(account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            if(!enterprise.getAreaId().equals(account.getAreaId())){
                return ResultUtils.resultWithoutData(ResultStatus.VISITED_FORBID);
            }
        }

        //检查企业下是否有监测点或者设备
        int deviceCount = deviceService.checkDeviceCountByAreaIdAndEnterpriseId(enterprise.getAreaId(), id);
        int siteCount = siteService.checkSiteCountByAreaIdAndEnterpriseId(enterprise.getAreaId(), id);
        if(deviceCount > 0){
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "该企业存有" + deviceCount + "台设备, 无法删除");
        }
        if(siteCount > 0){
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "该企业存有" + siteCount + "个监测点, 无法删除");
        }

        return enterpriseMapper.deleteById(id) == 1
                ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "删除企业信息成功")
                : ResultUtils.resultWithoutData(ResultStatus.FAILED, "删除企业信息失败");

    }

    /**
     * 分页获取企业信息
     * @param paramMap 参数集合
     * @param account 当前账户对象
     * @param page 第几页
     * @param size 一页几条数据
     * @return IPage<EnterpriseVo>
     */
    @Override
    @Transactional(readOnly = true)
    public IPage<EnterpriseVo> getEnterpriseVoList(Map<String, String[]> paramMap, Account account, Integer page, Integer size) {

        //获取客户端传过来的数组, 需要排除 page 和 size
        //需要过滤掉不必要的参数[防止恶意篡改 url 地址中的参数]
        String[] params = {"area_id","enterprise_name","detail_address","trade_id","enterprise_regulationtype"};
        //封装查询条件
        QueryWrapper<Enterprise> wrapper = new QueryWrapper<>();
        AtomicBoolean isArea = new AtomicBoolean(true);
        paramMap.forEach((k,v)->{
            for (String parm : params) {
                if(parm.equals(k) && !v[0].equals("")){
                    if(parm.equals("detail_address")){
                        wrapper.like(k, v[0]);
                        continue;
                    }
                    if(parm.equals("area_id")){
                        isArea.set(false);
                    }
                    wrapper.eq(k, v[0]);
                }
            }
        });

        if(isArea.get() && account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            //区级管理员
            wrapper.eq("area_id", account.getAreaId());
        }
        IPage<Enterprise> pageinfo1 = enterpriseMapper.selectPage(new Page<>(page, size), wrapper);
        List<Enterprise> enterpriseList = pageinfo1.getRecords();
        List<EnterpriseVo> enterpriseVos = this.toEnterpriseVo(enterpriseList);
        IPage<EnterpriseVo> pageInfo = new Page<>();

        pageInfo.setCurrent(pageinfo1.getCurrent());
        pageInfo.setRecords(enterpriseVos);
        pageInfo.setPages(pageinfo1.getPages());
        pageInfo.setSize(pageinfo1.getSize());
        pageInfo.setTotal(pageinfo1.getTotal());

        return pageInfo;

    }

    /**
     * 根据区域id查询企业列表
     * @param areaId 区域id
     * @return List<Enterprise>
     */
    @Override
    public List<Enterprise> getEnterpriseListByAreaId(Integer areaId) {

        return enterpriseMapper.selectList(new QueryWrapper<Enterprise>().eq("area_id", areaId));

    }

    /**
     * 修改企业信息
     * @param enterpriseVo 企业视图对象
     * @return Result
     */
    @Override
    public Result modifyEnterpriseInfo(EnterpriseVo enterpriseVo) {

        //获取该企业信息
        Enterprise enterprise = enterpriseMapper.selectById(enterpriseVo.getId());
        if(enterprise == null){
            return ResultUtils.resultWithoutData(ResultStatus.NOT_FOUND, "不存在该企业信息");
        }
        BeanUtil.copyProperties(enterpriseVo, enterprise);
        //判断企业法定负责人和环保负责人
        String lawuserName = enterpriseVo.getLawuserName();
        String environmentuserName = enterpriseVo.getEnvironmentuserName();
        if(lawuserName != null && !StringUtils.isEmpty(lawuserName)){
            Account lawuserAccount = accountMapper.getByAccName(lawuserName);
            if(lawuserAccount != null){
                enterprise.setLawUserid(lawuserAccount.getId());
            }else{
                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "企业法定代表人名字有误或该企业不存在该用户");
            }
        }else{
            enterprise.setLawUserid(null);
        }
        if(environmentuserName != null && !StringUtils.isEmpty(lawuserName)){
            Account environmentuserAccount = accountMapper.getByAccName(environmentuserName);
            if(environmentuserAccount != null){
                enterprise.setEnvironmentUserid(environmentuserAccount.getId());
            }else{
                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "企业环保负责人名字有误或该企业不存在该用户");
            }
        }else{
            enterprise.setEnvironmentUserid(null);
        }
        return enterpriseMapper.updateById(enterprise) == 1
                ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "更新企业信息成功")
                : ResultUtils.resultWithoutData(ResultStatus.FAILED, "更新企业信息失败");

    }

    /**
     * 判断企业中是否有该区域的企业, 返回个数
     * @param areaId 区域id
     * @return int
     */
    @Override
    public int checkEnterpriseArea(Integer areaId) {

        return enterpriseMapper.checkEnterpriseArea(areaId);

    }

    /**
     * 将 List<Enterprise> 转换成 List<EnterpriseVo>
     * @param enterprises 企业列表
     * @return List<EnterpriseVo>
     */
    private List<EnterpriseVo> toEnterpriseVo(List<Enterprise> enterprises){

        //声明变量
        List<EnterpriseVo> enterpriseVos = new ArrayList<>(enterprises.size());
        //遍历企业列表
        enterprises.forEach(enterprise -> {
            //1. 首先把相同的字段填充
            EnterpriseVo enterpriseVo = new EnterpriseVo();
            BeanUtil.copyProperties(enterprise, enterpriseVo);
            //2. 填充其他字段: areaName, tradeName, lawuserName, environmentuserName, pollutionSourceName, regulationName,
            // createUserName, updateUserName

            enterpriseVo.setAreaName(areaMapper.getAreaNameById(enterpriseVo.getAreaId()));
            enterpriseVo.setTradeName(tradetypeMapper.getTradeNameById(enterpriseVo.getTradeId()));
            enterpriseVo.setLawuserName(accountMapper.getAccNameById(enterpriseVo.getLawUserid()));
            enterpriseVo.setEnvironmentuserName(accountMapper.getAccNameById(enterpriseVo.getEnvironmentUserid()));
            enterpriseVo.setPollutionSourceName(pstm.getPstNameById(enterpriseVo.getPollutionSourcetype()));
            enterpriseVo.setRegulationName(regulationMapper.getRegulationNameById(enterpriseVo.getEnterpriseRegulationtype()));
            enterpriseVo.setCreateUserName(accountMapper.getAccNameById(enterpriseVo.getCreateUserid()));
            enterpriseVo.setUpdateUserName(accountMapper.getAccNameById(enterpriseVo.getUpdateUserid()));

            enterpriseVos.add(enterpriseVo);
        });

        return enterpriseVos;

    }

}
